package jf.collections;

import java.util.Set;
import java.util.Collection;

import jf.closure.F1B;

/**
 * @author ivanalx
 * @date 21.05.2009 15:06:00
 */
public interface SetX<A> extends Set<A>, CollectionX<A> {
	/**
	 * Add element to this collection and return it self
	 */
	public SetX<A> addToThis(A e);

	/**
	 * Add all elements to this collection and return it self
	 */
	public SetX<A> addToThis(Collection<? extends A> col);

	/**
	 * Add element into new set, that contains all elements from this one.
	 * @param e element to add
	 * @return new collection with old elements and new one
	 */
	public SetX<A> addX(A e);

	/**
	 * Add elements from collections in params into new set, that contains all elements from this one.
	 * @param col elements to add
	 * @return new collection with old elements and all new
	 */
	public SetX<A> addX(Collection<? extends A> col);

	/**
	 * Create new set, based on this and return it without element from parameter.
	 * @param e elements to remove
	 * @return new collection without element e
	 */
	public SetX<A> removeX(A e);

	/**
	 * Create new set, based on this and return it without all elements from parameter.
	 * @param col collection for remove
	 * @return  new collections without all elements from col
	 */
	public SetX<A> removeX(Collection<? extends A> col);

	/**
	 * Same as ratain, but work on 
	 * @param cols
	 * @return
	 */
	public SetX<A> retainX(A... cols);
	public SetX<A> retainX(Collection<? extends A> col);

	/**
	 * Defines the prefix of this object's toString representation.
	 */
	public boolean subsetOf(Set<A> that);

	/**
	 * Transform set to list
	 * @return
	 */
	public ListX<A> toList();

	/**
	 * Create new set and apply elem to new collection
	 */
	public SetX<A> apply(A elem);

	/**
	 * Create new collection and apply all elements to it;
	 */
	public SetX<A> applyAll(Collection<? extends A> c);

	/**
	 * Returns the longest prefix of this iterable whose elements satisfy the predicate p.
	 */
	public SetX<A> takeWhile(F1B<A> def);

	/**
	 * Returns the longest suffix of this iterable whose first element does not satisfy the predicate p.
	 */
	public SetX<A> dropWhile(F1B<A> def);

	/**
	 * Returns all the elements of this iterable that satisfy the predicate p.
	 */
	public SetX<A> filter(F1B<A> p);

	/**
	 * Remove all elements that satisfy the predicate filter
	 */
	public SetX<A> remove(F1B<A> f);

	/**
	 * unsafe cast this set to another with out any checking of content
	 */
	public <B> SetX<B> unsafeCastToOtherSet();

	/**
	 * Unsafe wider this set to another with out any checking of content
	 */
	public <B extends A> SetX<B> unsafeWider();

	/**
	 * Returns the longest prefix of the list whose elements all satisfy the given predicate,
	 * and the rest of the list.
	 */
	public Tuple2<SetX<A>, SetX<A>> span(F1B<A> f);

	/**
	 * Intersect. It computes an intersection with set that. It removes all the elements that are not present in that.
	 * This action does not modify target set 
	 */
	public SetX<A> intersect(Collection<? extends A> that);
}
